package cn.sc.jedis;

import cn.sc.jedis.serialization.DefaultSerialization;
import cn.sc.jedis.serialization.Serialization;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class JedisCluster implements RedisCommons{

    private final Serialization serialization;

    private final JedisClusterPool redisClusterPool;

    public JedisCluster(JedisClusterPool redisClusterPool, Serialization serialization){
        this.redisClusterPool = redisClusterPool;
        this.serialization = serialization != null ? serialization : new DefaultSerialization();
    }

    @Override
    public <V> V hSet(String key, String item, V value) {
        byte[] newKey = this.serialization.packString(key);
        byte[] newItem = this.serialization.packString(item);
        if(newKey == null || newItem == null){
            return null;
        }
        byte[] newValue = this.serialization.packObject(value);
        byte[] result = redisClusterPool.hSet(newKey, newItem, newValue);
        return this.serialization.dismantleObject(result);
    }

    @Override
    public <V> void hmset(String key, Map<String, V> values) {
        byte[] newKey = this.serialization.packString(key);
        Map<byte[], byte[]> newValue = this.serialization.packObjectMap(values);
        if(newKey == null || newValue == null){
            return;
        }
        redisClusterPool.hmset(newKey, newValue);
    }

    @Override
    public <V> V hGet(String key, String item) {
        byte[] newKey = this.serialization.packString(key);
        byte[] newItem = this.serialization.packString(item);
        if(newKey == null || newItem == null){
            return null;
        }
        byte[] result = redisClusterPool.hget(newKey, newItem);
        return this.serialization.dismantleObject(result);
    }

    @Override
    public <V> List<V> hGet(String key, String... items) {
        byte[] newKey = this.serialization.packString(key);
        byte[][] newItems = this.serialization.packStringMulti(items);
        if(newKey == null || newItems == null){
            return null;
        }
        List<byte[]> result = redisClusterPool.hmget(newKey, newItems);
        return this.serialization.dismantleMulti(result);
    }

    @Override
    public <V> Map<String, V> hGetAll(String key) {
        byte[] newKey = this.serialization.packString(key);
        if(newKey == null){
            return null;
        }
        Map<byte[], byte[]> result = redisClusterPool.hgetAll(newKey);
        return this.serialization.dismantleMap(result);
    }

    @Override
    public <V> List<V> hValues(String key) {
        byte[] newKey = this.serialization.packString(key);
        if(newKey == null){
            return null;
        }
        List<byte[]> result = new ArrayList<>(redisClusterPool.hvals(newKey));
        return this.serialization.dismantleMulti(result);
    }

    @Override
    public Set<String> hKeys(String key) {
        byte[] newKey = this.serialization.packString(key);
        if(newKey == null){
            return null;
        }
        Set<byte[]> result = redisClusterPool.hkeys(newKey);
        return this.serialization.dismantleStringMulti(result);
    }

    public Long del(final String key) {
        byte[] newKey = this.serialization.packString(key);
        if(newKey == null){
            return 0L;
        }
        return redisClusterPool.del(newKey);
    }

    @Override
    public Long hSize(String key) {
        byte[] newKey = this.serialization.packString(key);
        if(newKey == null){
            return 0L;
        }
        return redisClusterPool.hlen(newKey);
    }

    @Override
    public Long hDel(String key, String... items) {
        byte[] newKey = this.serialization.packString(key);
        byte[][] newItems = this.serialization.packStringMulti(items);
        if(newKey == null || newItems == null){
            return 0L;
        }
        return redisClusterPool.hdel(newKey, newItems);
    }

}
